package com.mjk.common.core.redis.limiter;

import org.redisson.api.RRateLimiter;
import org.redisson.api.RateIntervalUnit;
import org.redisson.api.RateType;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.data.redis.connection.DefaultedRedisConnection;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.RedisScript;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.concurrent.ConcurrentHashMap;

/**
 * reids 令牌桶
 *  last_mill_second 最后时间毫秒
	curr_permits 当前可用的令牌
	max_burst 令牌桶最大值
	rate 每秒生成几个令牌
	app 应用
 * @author mjk
 *
 */
@Service
@ConditionalOnProperty(name="bee.redis",havingValue="true")
public class RedisLimiter {

	@Autowired
	private RedissonClient redissonClient;

	private static final String RATE_LIMITER_KEY_PREFIX = "rateLimiter:";
	private final ConcurrentHashMap<String, RRateLimiter> rateLimiters = new ConcurrentHashMap<>();

	/**
	 *
	 * @param ip  每个IP地址
	 * @param permits  限流个个数
	 * @return
	 */
	public boolean acquireToken(String ip, int permits) {
		// 使用 IP 地址作为唯一标识符
		String rateLimiterKey = RATE_LIMITER_KEY_PREFIX + ip;

		// 获取或初始化令牌桶
		RRateLimiter rateLimiter = rateLimiters.computeIfAbsent(rateLimiterKey, key -> {
			RRateLimiter limiter = redissonClient.getRateLimiter(key);
			limiter.trySetRate(RateType.OVERALL, permits, 1, RateIntervalUnit.SECONDS); // 设置令牌生成速率
			return limiter;
		});

		// 尝试获取指定数量的令牌
		return rateLimiter.tryAcquire(permits);
	}
	/**
	 *
	 * @param ip  每个IP地址
	 * @param permits  限流个个数
	 * @param time  时间 单位秒
	 * @return
	 */
	public boolean acquireToken(String ip, int permits,long time) {
		// 使用 IP 地址作为唯一标识符
		String rateLimiterKey = RATE_LIMITER_KEY_PREFIX + ip;

		// 获取或初始化令牌桶
		RRateLimiter rateLimiter = rateLimiters.computeIfAbsent(rateLimiterKey, key -> {
			RRateLimiter limiter = redissonClient.getRateLimiter(key);
			limiter.trySetRate(RateType.OVERALL, permits, time, RateIntervalUnit.SECONDS); // 设置令牌生成速率
			return limiter;
		});

		// 尝试获取指定数量的令牌
		return rateLimiter.tryAcquire(permits);
	}
}
